package com.zhejiangzhengyuan.municipal_security.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zhejiangzhengyuan.municipal_common.annotation.AuthorizationLess;
import com.zhejiangzhengyuan.municipal_common.entity.Subject;
import com.zhejiangzhengyuan.municipal_common.entity.UserInfo;
import com.zhejiangzhengyuan.municipal_common.entity.dto.LoginDto;
import com.zhejiangzhengyuan.municipal_common.entity.dto.SubjectDto;
import com.zhejiangzhengyuan.municipal_common.entity.vo.DepartmentVo;
import com.zhejiangzhengyuan.municipal_common.entity.vo.RoleVo;
import com.zhejiangzhengyuan.municipal_common.entity.vo.SubjectVo;
import com.zhejiangzhengyuan.municipal_common.mapper.DepartmentMapper;
import com.zhejiangzhengyuan.municipal_common.mapper.RoleMapper;
import com.zhejiangzhengyuan.municipal_common.mapper.SubjectMapper;
import com.zhejiangzhengyuan.municipal_common.mapper.UserInfoMapper;
import com.zhejiangzhengyuan.municipal_common.response.ResponseVo;
import com.zhejiangzhengyuan.municipal_common.service.SubjectService;
import com.zhejiangzhengyuan.municipal_common.utils.ConstantUtil;
import com.zhejiangzhengyuan.municipal_common.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;

import java.util.List;

import static com.zhejiangzhengyuan.municipal_common.utils.JwtUtil.HEADER_STRING;
import static com.zhejiangzhengyuan.municipal_common.utils.httpUtils.OriginUtil.*;

/** @author lin_ju Create on 2019/11/25 */
@RestController
@Api(tags = "用户信息管理")
@RequestMapping("/security/subject")
@Slf4j
public class SubjectController {
  @Autowired private SubjectService subjectService;
  @Autowired private HttpServletRequest request;
  @Autowired private DepartmentMapper departmentMapper;
  @Autowired private RoleMapper roleMapper;
  @Autowired private UserInfoMapper userInfoMapper;
  @Autowired private SubjectMapper subjectMapper;
  @Autowired private BCryptPasswordEncoder encoder;

  @ApiOperation("用户查询")
  @RequestMapping(value = "/selectAllUserInfo", method = RequestMethod.GET)
  public ResponseVo selectAllUserInfo(@ApiParam("页码") Long page, @ApiParam("每页显示条数") Long limit) {

    // pageNo默认为1；size默认为10
    page = page == null || page <= 0 ? 1 : page;
    limit = limit == null || limit <= 0 ? 11 : limit;
    Page<SubjectVo> subjectVoPage = new Page<>(page, limit);
    Page<SubjectVo> subjectPage = subjectService.selectAllUserInfo(subjectVoPage);
    return subjectPage == null
        ? ResponseVo.SERVER_ERROR
        : new ResponseVo<>(ConstantUtil.ResultCode.SUCCESS, subjectVoPage);
  }

  @ApiOperation("添加用户")
  @RequestMapping(value = "/insertUserInfo", method = RequestMethod.POST)
  public ResponseVo insertUserInfo(@ModelAttribute SubjectDto dto) {
    return subjectService.insertUserInfo(dto) ? ResponseVo.SUCCESS : ResponseVo.SERVER_ERROR;
  }

  @ApiOperation("更新用户")
  @RequestMapping(value = "/updateUserInfo", method = RequestMethod.POST)
  public ResponseVo updateUserInfo(@ModelAttribute SubjectDto dto) {
    return subjectService.updateUserInfo(dto) ? ResponseVo.SUCCESS : ResponseVo.SERVER_ERROR;
  }

  @ApiOperation("个人中心")
  @RequestMapping(value = "/selectSubjectById", method = RequestMethod.GET)
  public ResponseVo selectSubjectById() {
    String token = request.getHeader(HEADER_STRING);
    Claims claims = JwtUtil.parseJWT(token);
    Long id = Long.valueOf(String.valueOf(claims.get("id")));
    SubjectVo subjectVo = subjectMapper.selectSubjectById(id);
    subjectVo.setDepartmentNames(departmentMapper.selectDepartmentListByUserId(subjectVo.getId()));
    return new ResponseVo<>(ConstantUtil.ResultCode.SUCCESS, subjectVo);
  }

  @ApiOperation("删除用户")
  @DeleteMapping(value = "/deleteUserInfo")
  public ResponseVo deleteUserInfo(Long id) {
    int i = subjectService.deleteUserInfo(id);
    return i > 0 ? ResponseVo.SUCCESS : ResponseVo.CLIENT_PARAM_ERROR;
  }

  @ApiOperation("根据用户名查询")
  @RequestMapping(value = "/findByName/{name}")
  public ResponseVo findByName(
      @PathVariable @ApiParam(value = "用户名", required = true) String name) {
    return subjectService.findByName(name);
  }

  @ApiOperation("根据ID查询")
  @RequestMapping(value = "/findById/{id}", method = RequestMethod.GET)
  public ResponseVo findById(@PathVariable @ApiParam(value = "用户Id", required = true) Long id) {
    return subjectService.findById(id);
  }

  @AuthorizationLess
  @ApiOperation("登录")
  @RequestMapping(value = "/login", method = RequestMethod.POST)
  public ResponseVo login(@ApiParam("登录请求参数") @RequestBody @Validated LoginDto loginDto) {
    Subject subject = subjectService.login(loginDto.getUsername(), loginDto.getPassword());
    // 验证是否登录成功 成功返回认证主体
    if (subject == null) {
      return new ResponseVo(ConstantUtil.HTTP_CODE.CLIENT_PARAM_ERROR, "用户名或密码错误");
    }
    // 判断时mobile 还是pc
    String origin = getOriginType(request.getHeader("User-Agent"));
    // /login
    UserInfo userInfo = userInfoMapper.selectUserInfoIdBySubject(subject.getId());
    String jwt = JwtUtil.createJWT(subject.getId(), subject.getSubjectName(), origin);
    JSONObject result = new JSONObject();
    result.put("jwt", jwt);
    result.put("userInfoId", userInfo.getId());
    return new ResponseVo<>(ConstantUtil.ResultCode.SUCCESS, result);
  }

  @ApiOperation("冻结账号")
  @RequestMapping(value = "/freeze", method = RequestMethod.DELETE)
  public ResponseVo delete(@PathVariable Integer id) {
    subjectService.freeze(id);
    return ResponseVo.SUCCESS;
  }

  @ApiOperation("部门新建编辑绑定")
  @GetMapping("/departmentVo")
  public ResponseVo DepartmentVo() {
    List<DepartmentVo> usernameVos = departmentMapper.usernameVo();
    return usernameVos == null
        ? ResponseVo.SERVER_ERROR
        : new ResponseVo<>(ConstantUtil.ResultCode.SUCCESS, usernameVos);
  }

  @ApiOperation("角色新建编辑绑定")
  @GetMapping("/RoleVo")
  public ResponseVo RoleVo() {
    List<RoleVo> usernameVos = roleMapper.RoleVo();
    return usernameVos == null
        ? ResponseVo.SERVER_ERROR
        : new ResponseVo<>(ConstantUtil.ResultCode.SUCCESS, usernameVos);
  }

  @ApiOperation("模糊查询")
  @GetMapping("/FuzzyUserInfoByRoleIdAndUserName")
  public ResponseVo FuzzyUserInfoByRoleIdAndUserName(String subject, String role) {
    Page<SubjectVo> subjectVoPage = new Page<>(0, 15);
    Page<SubjectVo> subjectVo =
        subjectService.FuzzyUserInfoByRoleIdAndUserName(subject, role, subjectVoPage);
    return new ResponseVo<>(ConstantUtil.ResultCode.SUCCESS, subjectVo);
  }
}
